package com.hjqjl.mvvmdemo.db;

import androidx.annotation.NonNull;
import androidx.room.Database;
import androidx.room.Room;
import androidx.room.RoomDatabase;
import androidx.room.migration.Migration;
import androidx.sqlite.db.SupportSQLiteDatabase;

import com.blankj.utilcode.util.LogUtils;
import com.hjqjl.mvvmdemo.MyApplication;
import com.hjqjl.mvvmdemo.model.User;

import java.util.List;

@Database(entities = {
        User.class}, version = 1)
public abstract class AppDatabase extends RoomDatabase {
    private static final String DATABASE_NAME = "user_db";

    public abstract UserDao userDao();

    private static volatile AppDatabase databaseInstance;

    /**
     * 获取数据库实例
     */
    public static AppDatabase getInstance() {
        if (databaseInstance == null) {
            synchronized (AppDatabase.class) {
                if (databaseInstance == null) {
                    Builder<AppDatabase> builder = Room
                            .databaseBuilder(MyApplication.getInstance().getApplicationContext(), AppDatabase.class, DATABASE_NAME);
//                    //内存中创建数据库，不用了就会被回收
//                    builder = Room.inMemoryDatabaseBuilder(context.getApplicationContext(), BookDB.class);
//                    // 添加构建SupportSQLiteOpenHelper的工厂，SQLiteOpenHelper就是在里面实现的，默认是FrameworkSQLiteOpenHelperFactory
//                    builder.openHelperFactory(null);
//                    // 数据库迁移操作添加，相当于SQLiteOpenHelper.onUpgrade的一些操作
//                    builder.addMigrations(MIGRATION_1_2);
                    builder.allowMainThreadQueries(); // 允许主线程执行查询操作
//                    // 有些APP的数据库需要预置数据，这两个就是导入预置数据库的
//                    builder.createFromAsset();
//                    builder.createFromFile()
//                    // 多进程需要调用，这个在inMemoryDatabaseBuilder没用
//                    builder.enableMultiInstanceInvalidation();
//                    // 允许破坏性迁移，数据会被丢弃
                    builder.fallbackToDestructiveMigration();
//                    // 允许特定版本迁移到当前版本进行破坏性迁移，数据会被丢弃
//                    builder.fallbackToDestructiveMigrationFrom(2, 3);
//                    // 允许降级破坏性迁移，数据会被丢弃
                    builder.fallbackToDestructiveMigrationOnDowngrade();
//                    // 这个默认就好，默认是WRITE_AHEAD_LOGGING
//                    builder.setJournalMode(JournalMode.WRITE_AHEAD_LOGGING);
//                    // 看名称就知道是啥，这两个都是ArchTaskExecutor，是fixed线程池，核心线程4个，一般来说是够用的
//                    builder.setQueryExecutor();
//                    builder.setTransactionExecutor();
//                    builder.addCallback(new Callback() {
//                        @Override
//                        public void onCreate(@NonNull SupportSQLiteDatabase db) {
//                            // 第一次创建数据库调用
//                            super.onCreate(db);
//                        }
//
//                        @Override
//                        public void onOpen(@NonNull SupportSQLiteDatabase db) {
//                            // 数据库打开调用
//                            super.onOpen(db);
//                        }
//
//                        @Override
//                        public void onDestructiveMigration(@NonNull SupportSQLiteDatabase db) {
//                            // 破坏性迁移
//                            super.onDestructiveMigration(db);
//                        }
//                    });
                    databaseInstance = builder.build();
                }
            }
        }
        return databaseInstance;
    }

    private static final Migration MIGRATION_1_2 = new Migration(1, 2) {

        @Override
        public void migrate(@NonNull SupportSQLiteDatabase database) {

        }
    };

    /**
     * 事物处理
     */
    public Boolean Transaction(List<String> sqlList) {
        SupportSQLiteDatabase db = databaseInstance.getOpenHelper().getWritableDatabase();
        // 开启事务
        db.beginTransaction();
        try {
            for (String sql : sqlList) {
                db.execSQL(sql);
            }
            // 设置事务标志为成功，当结束事务时就会提交事务
            db.setTransactionSuccessful();
            LogUtils.v("事物处理成功");
        } catch (Exception e) {
            LogUtils.e("事物处理失败");
            return false;
        } finally {
            // 结束事务
            db.endTransaction();
        }
        return true;
    }

    public static void closeDatabase() {
        if (databaseInstance != null && databaseInstance.isOpen()) {
            databaseInstance.close();
        }
    }
}
